package com.xmg.p2p.business.service.impl;

import com.xmg.p2p.base.domain.Account;
import com.xmg.p2p.base.domain.Userinfo;
import com.xmg.p2p.base.query.PageResult;
import com.xmg.p2p.base.query.QueryObject;
import com.xmg.p2p.base.service.IAccountService;
import com.xmg.p2p.base.service.IUserinfoService;
import com.xmg.p2p.base.util.BidConst;
import com.xmg.p2p.base.util.BitStatesUtils;
import com.xmg.p2p.base.util.UserContext;
import com.xmg.p2p.business.domain.BidRequest;
import com.xmg.p2p.business.domain.BidRequestAuditHistory;
import com.xmg.p2p.business.mapper.BidRequestAuditHistoryMapper;
import com.xmg.p2p.business.mapper.BidRequestMapper;
import com.xmg.p2p.business.service.IBidRequestService;
import com.xmg.p2p.business.util.CalculatetUtil;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class BidRequestServiceImpl implements IBidRequestService {
    @Autowired
    private BidRequestMapper bidRequestMapper;
    @Autowired
    private IUserinfoService userinfoService;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private BidRequestAuditHistoryMapper bidRequestAuditHistoryMapper;

    @Override
    public void update(BidRequest request) {
        int ret = bidRequestMapper.updateByPrimaryKey(request);
        if (ret == 0) {
            throw new RuntimeException("乐观锁失效 bidRequest:" + request.getId());
        }
    }

    @Override
    public boolean canApplyBidRequest(Long id) {
        Userinfo userinfo = userinfoService.get(id);
        return userinfo != null
                && userinfo.getIsRealAuth() && userinfo.getIsVideoAuth()
                && userinfo.getIsBasicInfo() && userinfo.getScore() >= BidConst.BASE_BORROW_SCORE
                && !userinfo.getHasBidRequestProcess();
    }

    @Override
    public void apply(BidRequest br) {
        Account account = accountService.getCurrent();
        if (canApplyBidRequest(UserContext.getCurrent().getId())
                && br.getBidRequestAmount().compareTo(BidConst.SMALLEST_BIDREQUEST_AMOUNT) >= 0
                && br.getBidRequestAmount().compareTo(account.getBorrowLimit()) <= 0
                && br.getCurrentRate().compareTo(BidConst.SMALLEST_CURRENT_RATE) >= 0
                && br.getCurrentRate().compareTo(BidConst.MAX_CURRENT_RATE) <= 0
                && br.getMinBidAmount().compareTo(BidConst.SMALLEST_BID_AMOUNT) >= 0) {
            BidRequest request = new BidRequest();
            request.setApplyTime(new Date());
            request.setBidRequestAmount(br.getBidRequestAmount());
            request.setCurrentRate(br.getCurrentRate());
            request.setBidRequestState(BidConst.BIDREQUEST_STATE_PUBLISH_PENDING);
            request.setCreateUser(UserContext.getCurrent());
            request.setDisableDays(br.getDisableDays());
            request.setTitle(br.getTitle());
            request.setMinBidAmount(br.getMinBidAmount());
            request.setDescription(br.getDescription());
            request.setReturnType(br.getReturnType());
            request.setMonthes2Return(br.getMonthes2Return());
            request.setTotalRewardAmount(CalculatetUtil.calTotalInterest(request.getReturnType(), request.getBidRequestAmount(), request.getCurrentRate(), request.getMonthes2Return()));
            bidRequestMapper.insert(request);
            Userinfo userinfo = userinfoService.getCurrent();
            userinfo.addState(BitStatesUtils.OP_HAS_BIDREQUEST_PROCESS);
            userinfoService.update(userinfo);
        }
    }

    @Override
    public PageResult query(QueryObject qo) {
        int count = bidRequestMapper.queryCount(qo);
        if(count>0){
            return new PageResult(bidRequestMapper.query(qo),count,qo.getCurrentPage(),qo.getPageSize());
        }
        return PageResult.empty(qo.getPageSize());
    }

    @Override
    public void publishAudit(Long id, String remark, int state) {
        BidRequest br = bidRequestMapper.selectByPrimaryKey(id);
        if(br!=null&&br.getBidRequestState()==BidConst.BIDREQUEST_STATE_PUBLISH_PENDING){
            BidRequestAuditHistory history = new BidRequestAuditHistory();
            history.setAuditType(BidRequestAuditHistory.PUBLISH_AUDIT);
            history.setApplier(br.getCreateUser());
            history.setAuditor(UserContext.getCurrent());
            history.setApplyTime(br.getApplyTime());
            history.setBidRequestId(br.getId());
            history.setAuditTime(new Date());
            history.setState(state);
            history.setRemark(remark);
            bidRequestAuditHistoryMapper.insert(history);
            if(state==BidRequestAuditHistory.STATE_PASS){
                br.setBidRequestState(BidConst.BIDREQUEST_STATE_BIDDING);
                br.setDisableDate(DateUtils.addDays(new Date(),br.getDisableDays()));
                br.setNote(remark);
            }else {
                br.setBidRequestState(BidConst.BIDREQUEST_STATE_PUBLISH_REFUSE);
                br.setNote(remark);
                Userinfo applier = userinfoService.get(br.getCreateUser().getId());
                applier.removeState(BitStatesUtils.OP_HAS_BIDREQUEST_PROCESS);
                userinfoService.update(applier);
            }
            update(br);
        }

    }

    @Override
    public BidRequest selectByKey(Long id) {
        return bidRequestMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<BidRequestAuditHistory> listAuditHistoryByBidRequest(Long id) {
        return bidRequestAuditHistoryMapper.listByBidRequest(id);
    }

    @Override
    public List<BidRequest> indexList(int i) {
        return null;
    }
}
